package com.xl.web.service.sys;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xl.base.annotation.DataSource;
import com.xl.base.service.BaseService;
import com.xl.core.enums.CommonEnum;
import com.xl.core.enums.SourceEnum;
import com.xl.core.util.json.JSONUtil;
import com.xl.web.dao.sys.SysMenuBtnDao;
import com.xl.web.dao.sys.SysMenuDao;
import com.xl.web.dao.sys.SysRoleDao;
import com.xl.web.entity.sys.SysMenu;
import com.xl.web.entity.sys.SysMenuBtn;
import com.xl.web.entity.sys.SysRole;

/**
 * 菜单操作Service
 * 
 * @author 梁华
 * 
 * @param <T>
 */
@Service("sysMenuService")
public class SysMenuService<T extends SysMenu> extends BaseService<SysMenu> {

	// 菜单基础Dao
	@Autowired(required = false)
	private SysMenuDao<SysMenu> sysMenuDao;

	// 菜单按钮基础Dao
	@Autowired(required = false)
	private SysMenuBtnDao<SysMenuBtn> sysMenuBtnDao;

	// 角色基础Dao
	@Autowired(required = false)
	private SysRoleDao<SysRole> sysRoleDao;

	public SysMenuDao<SysMenu> getDao() {
		return sysMenuDao;
	}

	/**
	 * 删除数据
	 */
	@Override
	public void delete(Object... ids) throws Exception {
		if (ids == null || ids.length < 1) {
			return;
		}
		for (Object id : ids) {
			// 获取按钮权限
			SysMenuBtn btn = new SysMenuBtn();
			btn.setMenuId(String.valueOf(id));
			btn.getPager().setLimitDirection(false);
			List<SysMenuBtn> btnList = this.sysMenuBtnDao.queryByList(btn);
			if (btnList != null && btnList.size() > 0) {
				for (SysMenuBtn menuBtn : btnList) {
					this.sysRoleDao.deleteRoleMenuByMenuId(menuBtn.getId());
					this.sysMenuBtnDao.delete(menuBtn.getId());
				}
			}
			this.sysRoleDao.deleteRoleMenuByMenuId(id);
			getDao().delete(id);
		}
	}

	/**
	 * 获取树形结构数据
	 * 
	 * @return
	 */
	@DataSource(source = SourceEnum.TYPE_SLAVE)
	public String getTreeList(SysRole role) {

		// 获取所有已选择菜单与按钮的Id
		Set<String> selectedMenuID = new HashSet<String>();

		List<SysMenu> selectedMenu = role.getMenuList();
		while (selectedMenu != null && selectedMenu.size() > 0) {
			selectedMenuID.add(selectedMenu.remove(0).getId());
		}

		List<SysMenuBtn> selectedMenuBtn = role.getMenuBtnList();
		while (selectedMenuBtn != null && selectedMenuBtn.size() > 0) {
			selectedMenuID.add(selectedMenuBtn.remove(0).getId());
		}

		// 获取所有的一级菜单
		SysMenu ckMenu = new SysMenu();
		ckMenu.getPager().setOrderField("create_date");
		ckMenu.getPager().setLimitDirection(false);
		ckMenu.setMenuGrade(CommonEnum.menu_grade.GRADE_1.getValue());
		List<SysMenu> menuList = getDao().queryByList(ckMenu);

		// 生成树形菜单所需字符串
		List<Map<String, Object>> treeList = new ArrayList<Map<String, Object>>();
		Map<String, Object> treeMap = null;

		// 子菜单
		List<Map<String, Object>> childTreeList = null;
		Map<String, Object> childTreeMap = null;

		// 菜单按钮
		List<Map<String, Object>> menuBtnList = null;
		Map<String, Object> menuBtnMap = null;

		for (SysMenu menu : menuList) {
			treeMap = new HashMap<String, Object>();
			treeMap.put("id", menu.getId());
			treeMap.put("text", menu.getMenuName());
			treeMap.put("value", menu.getId());
			treeMap.put("showcheck", true);

			// 子菜单
			List<SysMenu> childMenuList = menu.getChildMenuList();
			if (childMenuList != null && childMenuList.size() > 0) {
				treeMap.put("isexpand", true);
				treeMap.put("hasChildren", true);
				childTreeList = new ArrayList<Map<String, Object>>();

				int checked = 0;
				for (SysMenu child : childMenuList) {
					childTreeMap = new HashMap<String, Object>();
					childTreeMap.put("id", child.getId());
					childTreeMap.put("text", child.getMenuName());
					childTreeMap.put("value", child.getId());
					childTreeMap.put("showcheck", true);

					// 获取按钮权限
					SysMenuBtn btn = new SysMenuBtn();
					btn.setMenuId(child.getId());
					btn.getPager().setLimitDirection(false);
					List<SysMenuBtn> btnList = sysMenuBtnDao.queryByList(btn);

					if (btnList != null && btnList.size() > 0) {

						childTreeMap.put("isexpand", true);
						childTreeMap.put("hasChildren", true);
						menuBtnList = new ArrayList<Map<String, Object>>();

						int btnChecked = 0;
						for (SysMenuBtn childBtn : btnList) {
							menuBtnMap = new HashMap<String, Object>();
							menuBtnMap.put("id", childBtn.getId());
							menuBtnMap.put("text", childBtn.getBtnName());
							menuBtnMap.put("value", childBtn.getId());
							menuBtnMap.put("showcheck", true);

							if (selectedMenuID.contains(childBtn.getId())) {
								menuBtnMap.put("checkstate", 1);
								btnChecked++;
							} else {
								menuBtnMap.put("checkstate", 0);
							}
							menuBtnMap.put("ChildNodes", null);
							menuBtnMap.put("isexpand", false);
							menuBtnMap.put("hasChildren", false);
							menuBtnMap.put("complete", false);
							menuBtnList.add(menuBtnMap);
						}

						if (btnChecked == btnList.size()) {
							checked++;
							childTreeMap.put("checkstate", 1);
						} else if (btnChecked > 0) {
							childTreeMap.put("checkstate", 2);
						} else {
							childTreeMap.put("checkstate", 0);
						}
						childTreeMap.put("ChildNodes", menuBtnList);

					} else {

						if (selectedMenuID.contains(child.getId())) {
							childTreeMap.put("checkstate", 1);
							checked++;
						} else {
							childTreeMap.put("checkstate", 0);
						}
						childTreeMap.put("ChildNodes", null);
						childTreeMap.put("isexpand", false);
						childTreeMap.put("hasChildren", false);
					}

					childTreeMap.put("complete", false);
					childTreeList.add(childTreeMap);
				}

				if (checked == childMenuList.size()) {
					treeMap.put("checkstate", 1);
				} else if (checked > 0) {
					treeMap.put("checkstate", 2);
				} else {
					treeMap.put("checkstate", 0);
				}
				treeMap.put("ChildNodes", childTreeList);

			} else {
				treeMap.put("isexpand", false);
				treeMap.put("hasChildren", false);
				treeMap.put("ChildNodes", null);
				if (selectedMenuID.contains(menu.getId())) {
					treeMap.put("checkstate", 1);
				} else {
					treeMap.put("checkstate", 0);
				}
			}
			treeMap.put("complete", false);
			treeList.add(treeMap);
		}

		String jsonStr = JSONUtil.toJSONString(treeList);
		return jsonStr;
	}
}
